package com.suntoon.framework.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.generator.SnowflakeGenerator;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.suntoon.framework.common.Constants;
import lombok.extern.slf4j.Slf4j;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: LEAVES
 * @Version 1.0
 * @Date: 2021年06月21日 17时52分19秒
 * @Description:
 */
@Slf4j
public class JwtTokenUtil {

    /**
     * 校验token是否正确（检验是否需要更新token）
     *
     * @param token
     * @param username
     * @return
     */
    public static boolean verify(String token, String username) {
        log.info("执行JwtUtil的verify()方法");
        try {
            //根据密码生成JWT效验器
            Algorithm algorithm = Algorithm.HMAC256(Constants.TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim("username", username)
                    //.withClaim("password",password)
                    .build();
            //效验TOKEN
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的登录名
     *
     * @return token中包含的用户名
     */
    public static String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            log.info(e.getMessage());
            return null;
        }
    }

    /**
     * 生成token签名    EXPIRE_TIME 分钟后过期
     *
     * @param username 用户名
     * @return 加密的token
     */
    public static String sign(String userId, String username) {
        Map<String, Object> header = new HashMap<>();
        header.put("type", "Jwt");
        header.put("alg", "HS256");
        long currentTimeMillis = System.currentTimeMillis();
        //设置token过期时间
        Date date = new Date(currentTimeMillis + Constants.TOKEN_EXPIRE_TIME);
        Algorithm algorithm = Algorithm.HMAC256(Constants.TOKEN_SECRET);
        // 附带username信息
        return JWT.create()
                .withHeader(header)
                .withClaim("username", username)
                .withClaim("userId", userId)
                .withClaim("currentTime", currentTimeMillis)
                .withExpiresAt(date)
                .sign(algorithm);

    }

    public static String getAccount(String token) {
        try {
            DecodedJWT decodedJWT = JWT.decode(token);
            return decodedJWT.getClaim("username").asString();

        } catch (JWTCreationException e) {
            return null;
        }
    }

    public static Long getCurrentTime(String token) {
        try {
            DecodedJWT decodedJWT = JWT.decode(token);
            return decodedJWT.getClaim("currentTime").asLong();

        } catch (JWTCreationException e) {
            return null;
        }
    }

    public static void main(String[] args) {
        /**
         * 测试生成一个token
         */
        Long next = new SnowflakeGenerator().next();
        String encode = Base64Util.encode(String.valueOf(next));
        System.out.println("next = " + next);
        System.out.println("encode = " + encode);
        String sign = sign(encode, "张三");
        log.info("测试生成一个token\n " + sign);

        Long currentTime = getCurrentTime(sign);
        System.out.println("currentTime = " + currentTime);
        DecodedJWT decodedJWT = JWT.decode(sign);
        String userId = decodedJWT.getClaim("userId").asString();
        System.out.println("userId = " + userId);
        String decode = Base64Util.decode(userId);
        System.out.println("decode = " + decode);
        Date expiresAt = decodedJWT.getExpiresAt();
        System.out.println("expiresAt = " + expiresAt);
        String format = DateUtil.format(expiresAt, "yyyy-MM-dd HH:mm:ss");
        System.out.println("format = " + format);
        String token = "Bearer eyJ0eXBlIjoiSnd0IiwiYWxnIjoiSFMyNTYiLCJ0eXAiOiJKV1QifQ.eyJjdXJyZW50VGltZSI6MTYyNDUyMTUxNzA1NywiZXhwIjoxNjI0NTM5NTE3LCJ1c2VySWQiOiJNVFF3TnprM01UUXdOelEyTXpFNE5qUXpNZz09IiwidXNlcm5hbWUiOiLlvKDkuIkifQ.q0m_mhXkCdaAh-5B1FbGvSqKKFgp3JXAA40f7W9sobQ";
        boolean verify = verify(token, "张三");

        System.out.println("verify = " + verify);

    }
}
